﻿using System;

namespace Sgr.Domain.Uow.Database
{
    /// <summary>
    /// 事务API容器接口
    /// </summary>
    /// <remarks>
    /// 提供事务API的管理功能，包括：
    /// 1. 管理事务API的注册和查找
    /// 2. 支持按需创建事务API
    /// 3. 确保事务API的唯一性和可追踪性
    /// </remarks>
    public interface ITransactionApiContainer
    {
        /// <summary>
        /// 获取当前容器中事务API的总数
        /// </summary>
        /// <returns>已注册的事务API数量</returns>
        int CountTransactionApi();

        /// <summary>
        /// 判断指定键的事务API是否存在
        /// </summary>
        /// <param name="key">事务API的唯一标识键</param>
        /// <remarks>
        /// 检查容器中是否包含指定键的事务API：
        /// - 建议使用统一的命名规范，如：{数据库名}.{事务类型}
        /// - 仅检查是否存在，不返回具体实例
        /// </remarks>
        /// <returns>如果存在返回true，否则返回false</returns>
        bool AnyTransactionApi(string key);

        /// <summary>
        /// 查找指定键的事务API
        /// </summary>
        /// <param name="key">事务API的唯一标识键（例如："database1.transaction"）</param>
        /// <remarks>
        /// 用于查找已注册的事务API：
        /// - key参数区分大小写
        /// - 建议使用统一的命名规范，如：{数据库名}.{事务类型}
        /// - 如果未找到指定的事务API，返回null
        /// </remarks>
        /// <returns>找到的事务API实例，如果未找到则返回null</returns>
        ITransactionApi? FindTransactionApi(string key);

        /// <summary>
        /// 添加事务API到容器中
        /// </summary>
        /// <param name="key">事务API的唯一标识键</param>
        /// <param name="api">要添加的事务API实例</param>
        /// <remarks>
        /// 添加新的事务API实例：
        /// - 如果key已存在，将抛出异常
        /// - api实例必须是有效的（非null）
        /// - 添加后的api实例由容器负责管理其生命周期
        /// </remarks>
        void AddTransactionApi(string key, ITransactionApi api);

        /// <summary>
        /// 获取或创建事务API
        /// </summary>
        /// <param name="key">事务API的唯一标识键</param>
        /// <param name="factory">创建事务API的工厂方法</param>
        /// <remarks>
        /// 获取或创建事务API实例：
        /// 1. 首先尝试获取已存在的事务API
        /// 2. 如果不存在，则使用工厂方法创建新实例
        /// 3. 新创建的实例会自动添加到容器中
        ///
        /// 注意：
        /// - factory不应返回null
        /// - 创建的实例应该是线程安全的
        /// - 实例的释放由容器负责管理
        /// </remarks>
        /// <returns>已存在的或新创建的事务API实例</returns>
        ITransactionApi GetOrAddTransactionApi(string key, Func<ITransactionApi> factory);
    }
}